package com.rdgk.newtech.service.impl;

import com.rdgk.newtech.dao.*;
import com.rdgk.newtech.service.NewTechAnalyseService;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class NewTechAnalyseServiceImpl implements NewTechAnalyseService {
    @Autowired
    private TechniqueArticleDao techArticleDao;
    @Autowired
    private PaperDao paperDao;
    @Autowired
    private PatentDao patentDao;
    @Autowired
    private CraOrganizationDao organizationDao;
    @Autowired
    private TechniqueWordDao techniqueWordDao;
    @Autowired
    private CraAuthorDao authorDao;

    @Override
    public List<Map<String,Object>> latestTechnologyTrends(Integer topicId, String[] words) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        return techArticleDao.listArticle(params);
    }

    @Override
    public Map<String, Object> technologyDevelopmentTrends(Integer topicId, String[] words, Date startDate, Date endDate) {
        Map<String,Object> params = new HashMap<String,Object>();
        Map<String,Object> results = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("startDate",startDate);
        params.put("endDate",endDate);
        List<Map<String,Object>> alldata = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> techNumList = techArticleDao.StatisticsNumByYear(params);
        List<Map<String,Object>> paperNumList = paperDao.StatisticsNumByYear(params);
        List<Map<String,Object>> patentNumList = patentDao.StatisticsNumByYear(params);
        alldata.addAll(techNumList);
        alldata.addAll(paperNumList);
        alldata.addAll(patentNumList);
        if(alldata.size()<=0)
            return  results;
        List<Integer> years = new ArrayList<Integer>();
        for (Map<String,Object> data:alldata
             ) {
            if(!years.contains(data.get("publishyear"))){
                years.add((Integer) data.get("publishyear"));
            }
        }

        Collections.sort(years);

        int[] articleNum = new int[years.size()];
        int[] paperNum = new int[years.size()];
        int[] patentNum = new int[years.size()];

        for (Map<String,Object> data:techNumList
                ) {
            articleNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
        }
        for (Map<String,Object> data:paperNumList
                ) {
            paperNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
        }
        for (Map<String,Object> data:patentNumList
                ) {
            patentNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
        }

        results.put("years",years);
        results.put("articleNum",articleNum);
        results.put("paperNum",paperNum);
        results.put("patentNum",patentNum);
        return results;
    }

    @Override
    public Map<String, Object> technologyDevelopmentTrends(Integer topicId, String[] words, Date startDate, Date endDate,String dateType,String category) {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("dateType",dateType);
        map.put("category",category);

        Map<String, Object> results = technologyDevelopmentTrends(map, topicId, words, startDate, endDate);
//        if(map != null){
//            return results;
//        }

        List<Integer> years = (List<Integer>)results.get("years");


        int[] articleNum = (int[])results.get("articleNum");
        int[] paperNum = (int[])results.get("paperNum");
        int[] patentNum = (int[])results.get("patentNum");

        String format = "yyyy-MM-dd";
        if("month".equals(dateType.toLowerCase())){
            String s1 = DateFormatUtils.format(startDate, format);
            String sm = s1.split("-")[1];

            String e1 = DateFormatUtils.format(endDate, format);
            String em = e1.split("-")[1];

            int index=0;
            int interval = Integer.valueOf(em) - Integer.valueOf(sm)+1;
            int[] articleNum2 = new int[interval];
            int[] paperNum2 = new int[interval];
            int[] patentNum2 = new int[interval];
            List<Integer> years2 = new ArrayList<>();

            for(int x = Integer.valueOf(sm);x<=Integer.valueOf(em);x++){
                years2.add(x);
                {

                    articleNum2[index] = 0;
                    paperNum2[index] = 0;
                    patentNum2[index] = 0;
                }
                index++;
            }

            for(int i=0;years!=null&&i<years.size();i++){
                Integer y1 = years.get(i);
                articleNum2[y1] =  articleNum[i];
                paperNum2[y1] =  paperNum[i];
                patentNum2[y1] =  patentNum[i];
            }


            results.put("years",years2);
            results.put("articleNum",articleNum2);
            results.put("paperNum",paperNum2);
            results.put("patentNum",patentNum2);

        }
        return results;
    }

    @Override
    public Map<String, Object> technologyDevelopmentTrends(Integer topicId, String[] words, Date startDate, Date endDate,String dateType) {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("dateType",dateType);

        return technologyDevelopmentTrends(map,topicId,words,startDate,endDate);
    }

    public Map<String, Object> technologyDevelopmentTrends(Map<String,Object> params,Integer topicId, String[] words, Date startDate, Date endDate) {
//        String category = String.valueOf(params.get("category"));
        Map<String,Object> results = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("startDate",startDate);
        params.put("endDate",endDate);

        List<Map<String,Object>> techNumList  = new ArrayList<>();
        List<Map<String,Object>> paperNumList  = new ArrayList<>();
        List<Map<String,Object>> patentNumList  = new ArrayList<>();

        List<Map<String,Object>> alldata = new ArrayList<Map<String,Object>>();
        if(ObjectUtils.isEmpty(params.get("category"))){
            techNumList = techArticleDao.StatisticsNumByYear(params);
            paperNumList = paperDao.StatisticsNumByYear(params);
            patentNumList = patentDao.StatisticsNumByYear(params);
            alldata.addAll(techNumList);
            alldata.addAll(paperNumList);
            alldata.addAll(patentNumList);

        }else{
            String category = String.valueOf(params.get("category"));
            if("news".equals(category.toLowerCase())){
               techNumList = techArticleDao.StatisticsNumByYear(params);
                alldata.addAll(techNumList);
            }else if("paper".equals(category.toLowerCase())){
                paperNumList = paperDao.StatisticsNumByYear(params);
                alldata.addAll(paperNumList);
            }else if("patent".equals(category.toLowerCase())){
                patentNumList = patentDao.StatisticsNumByYear(params);
                alldata.addAll(patentNumList);
            }
        }
        if(alldata.size()<=0)
            return  results;
        List<Integer> years = new ArrayList<Integer>();
        for (Map<String,Object> data:alldata
             ) {
            if(data.get("publishyear")!=null && !years.contains(data.get("publishyear"))){
                years.add((Integer) data.get("publishyear"));
            }
        }

        Collections.sort(years);

        int[] articleNum = new int[years.size()];
        int[] paperNum = new int[years.size()];
        int[] patentNum = new int[years.size()];

        for (Map<String,Object> data:techNumList
                ) {
            articleNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
        }
        for (Map<String,Object> data:paperNumList
                ) {
            if(data.get("publishyear")!=null)
                paperNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
        }
        for (Map<String,Object> data:patentNumList
                ) {
            patentNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
        }

        results.put("years",years);
        results.put("articleNum",articleNum);
        results.put("paperNum",paperNum);
        results.put("patentNum",patentNum);
        return results;
    }

    public Map<String, Object> technologyDevelopmentTrends_news(Map<String,Object> params,Integer topicId, String[] words, Date startDate, Date endDate) {
        String category = String.valueOf(params.get("category"));
        Map<String,Object> results = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("startDate",startDate);
        params.put("endDate",endDate);
        List<Map<String,Object>> alldata = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> techNumList = techArticleDao.StatisticsNumByYear(params);
//        List<Map<String,Object>> paperNumList = paperDao.StatisticsNumByYear(params);
//        List<Map<String,Object>> patentNumList = patentDao.StatisticsNumByYear(params);
        alldata.addAll(techNumList);
//        alldata.addAll(paperNumList);
//        alldata.addAll(patentNumList);
        if(alldata.size()<=0)
            return  results;
        List<Integer> years = new ArrayList<Integer>();
        for (Map<String,Object> data:alldata
                ) {
            if(!years.contains(data.get("publishyear"))){
                years.add((Integer) data.get("publishyear"));
            }
        }

        Collections.sort(years);

        int[] articleNum = new int[years.size()];
        int[] paperNum = new int[years.size()];
        int[] patentNum = new int[years.size()];

        for (Map<String,Object> data:techNumList
                ) {
            articleNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
        }
//        for (Map<String,Object> data:paperNumList
//                ) {
//            paperNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
//        }
//        for (Map<String,Object> data:patentNumList
//                ) {
//            patentNum[years.indexOf(data.get("publishyear"))] = data.get("num")==null?0:((Long)data.get("num")).intValue();//将统计数字放到对应的年份中去
//        }

        results.put("years",years);
        results.put("articleNum",articleNum);
//        results.put("paperNum",paperNum);
//        results.put("patentNum",patentNum);
        return results;
    }

    @Override
    public List<Map<String,Object>> technologyDevelopmentCours(Integer topicId, String category) {
        List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        if(category == null || "news".equals(category))
            results.addAll(techArticleDao.listByYear(params));
        if(category == null || "paper".equals(category))
            results.addAll(paperDao.listByYear(params));
        if(category == null || "patent".equals(category))
            results.addAll(patentDao.listByYear(params));
        return results;
    }

    @Override
    public Map<String, Object> technologyHotspot(Integer topicId, String[] words) {//待测试，一个月以内的算热词（未设置）
        //先通过主题找到相关关键词，然后根据关键词与网络新闻动态的关系表找到网络新闻动态
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        Map<String,Object> results = new HashMap<String,Object>();
        params.put("topicId",topicId);
        List<Map<String,Object>> articleNumList = techArticleDao.StatisticsNumByHotword(params);
        List<Map<String,Object>> paperNumList = paperDao.StatisticsNumByHotword(params);
        List<Map<String,Object>> patentNumList = patentDao.StatisticsNumByHotword(params);
        Map<String,Integer[]> hotwords = new HashMap<String,Integer[]>();
        List<String> hotwordStr = new ArrayList<String>();

        for (Map<String,Object>articleNum : articleNumList
             ) {//每个热词的新闻动态数量存放在数组第二个元素中，总和放在数组第一个元素中
            Integer[] wordNum = new Integer[4];
            wordNum[0] = ((Long)articleNum.get("datanum")).intValue();
            wordNum[1] = ((Long)articleNum.get("datanum")).intValue();
            hotwords.put((String)articleNum.get("keyword"),wordNum);
        }

        for (Map<String,Object>patentNum : patentNumList
                ) {//每个热词的新闻动态数量存放在数组第三个元素中，计算总和放在数组第一个元素中
            String keyword = (String)patentNum.get("keyword");
            Integer[] wordNum = hotwords.get(keyword);
            Integer datanum = ((Long) patentNum.get("datanum")).intValue();
            wordNum[2] = datanum;
            wordNum[0] += datanum;
        }

        for (Map<String,Object>paperNum : paperNumList
                ) {//每个热词的新闻动态数量存放在数组第三个元素中，计算总和放在数组第一个元素中
            String keyword = (String)paperNum.get("keyword");
            Integer[] wordNum = hotwords.get(keyword);
            Integer datanum = ((Long) paperNum.get("datanum")).intValue();
            wordNum[3] = datanum;
            wordNum[0] += datanum;
        }
        Integer[] articleNum = new Integer[hotwords.size()];//每个热词的新闻动态数量
        Integer[] paperNum = new Integer[hotwords.size()];//每个热词的论文数量
        Integer[] patentNum = new Integer[hotwords.size()];//每个热词的专利数量

        List<Map.Entry<String, Integer[]>> hotwordList = new ArrayList<Map.Entry<String, Integer[]>>(hotwords.entrySet()); //转换为list
        hotwordList.sort(new Comparator<Map.Entry<String, Integer[]>>() {//按照每个热词新闻动态、论文和专利的数量之和进行排序
            @Override
            public int compare(Map.Entry<String, Integer[]> o1, Map.Entry<String, Integer[]> o2) {
                return o2.getValue()[0]-o1.getValue()[0];
            }
        });

        for (int i = 0; i < hotwordList.size(); i++) {
            Map.Entry<String, Integer[]> hotwordnum = hotwordList.get(i);
            hotwordStr.add(hotwordnum.getKey());
            articleNum[i] = hotwordnum.getValue()[1];
            paperNum[i] = hotwordnum.getValue()[3];
            patentNum[i] = hotwordnum.getValue()[2];
        }
        results.put("keyword",hotwordStr);
        results.put("articleNum",articleNum);
        results.put("paperNum",paperNum);
        results.put("patentNum",patentNum);
        return results;
    }

    @Override
    public List<Map<String,Object>> technologyRegionalDistribution(Integer topicId, String[] words) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        List<Map<String,Object>> data = organizationDao.statisticsNumByAddressForMap(params);
        data.addAll(organizationDao.statisticsOrgNumForMap(params));
        data.addAll(authorDao.statisticsAuthorNumForMap(params));
        return data;
    }

    @Override
    public List<Map<String,Object>> technologySourceDistribution(Integer topicId, String[] words) {//待测试，专利表没有source字段
        List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        results.addAll(techArticleDao.StatisticsNumBySource(params));
        results.addAll(paperDao.StatisticsNumBySource(params));
        results.addAll(patentDao.StatisticsNumBySource(params));
        return results;
    }

    @Override
    public List<Map<String,Object>> technologySourceDistribution_news(Integer topicId, String[] words) {//待测试，专利表没有source字段
        List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        results.addAll(techArticleDao.StatisticsNumBySource(params));
        return results;
    }

    @Override
    public List<Map<String,Object>> technologySourceDistribution_paper(Integer topicId, String[] words) {//待测试，专利表没有source字段
        List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        results.addAll(paperDao.StatisticsNumBySource(params));
        return results;
    }
    @Override
    public List<Map<String,Object>> technologySourceDistribution_patent(Integer topicId, String[] words) {//待测试，专利表没有source字段
        List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        results.addAll(patentDao.StatisticsNumBySource(params));
        return results;
    }

    @Override
    public Map<String, Object> hotWordsAtlas(Integer topicId, String keyword,String category){
        Map<String,Object> results = new HashMap<String,Object>();
        List<Map<String,Object>> nodes = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> edges = new ArrayList<Map<String,Object>>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("category",category);
        List<Map<String,Object>> hotwordRelations = techniqueWordDao.getHotwordsByRelation(params);
        List<Object> tmpHotwordIds = new ArrayList<Object>();//临时存放热词id的list，用于去重
        Map<String,Object> articleIncludeWords = new HashMap<String,Object>();//用于记录每个动态包含的关键词
        Map<String,Integer> relIndex = new HashMap<String,Integer>();//用于记录每个关系在Edges中的下标
        for (Map<String,Object> wordRelation:hotwordRelations
                ) {
            Object wordid = wordRelation.get("wordid");
            Object articleid = wordRelation.get("articleid");
            if (!tmpHotwordIds.contains(wordid)) {
                Map<String, Object> wordNode = new HashMap<String, Object>();//创建机构节点
                wordNode.put("id", wordRelation.get("wordid"));
                wordNode.put("label", wordRelation.get("keyword"));
                wordNode.put("weight", 1);
                nodes.add(wordNode);
                tmpHotwordIds.add(wordid);//标记该热词已经出现过
            } else {//更新热词权重
                Map<String, Object> wordNode = nodes.get(tmpHotwordIds.indexOf(wordid));
                Integer weight = ((Integer) wordNode.get("weight")) + 1;
                wordNode.put("weight", weight);
            }
        }

        results.put("words",nodes);
        return results;
    }

    @Override
    public Map<String, Object> hotWordsAtlasNews(Integer topicId, String keyword) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("keyword",keyword);
        Map<String,Object> results = new HashMap<String,Object>();

        List<Map<String,Object>> hotWordNodes = new ArrayList<Map<String,Object>>();//热词节点
        List<Map<String,Object>> techniqueArticleNodes = new ArrayList<Map<String,Object>>();//网络新闻动态节点
        List<Map<String,Object>> paperNodes = new ArrayList<Map<String,Object>>();//论文节点
        List<Map<String,Object>> patentNodes = new ArrayList<Map<String,Object>>();//专利节点
        List<Map<String,Object>> authorNodes = new ArrayList<Map<String,Object>>();//专家节点
        List<Map<String,Object>> organizationNodes = new ArrayList<Map<String,Object>>();//机构节点

//        hotWordNodes = techniqueWordDao.getHotwords(params);//获取领域属于热词的关键词
        List<Map<String,Object>> hotwordArticle = techArticleDao.getArticleByHotword(params);
        List<Object> articleIdParams = new ArrayList<Object>();//用于传递参数的网络新闻动态id的集合
        for (Map<String,Object> article:hotwordArticle
                ) {
            if(!articleIdParams.contains(article.get("articleid"))){
                Map<String,Object> techniqueArticle = new HashMap<String,Object>();//创建网络动态节点
                techniqueArticle.put("id","tech_"+article.get("articleid"));
                techniqueArticle.put("label",article.get("title"));
                techniqueArticleNodes.add(techniqueArticle);
                articleIdParams.add(article.get("articleid"));//保存每个网络新闻动态的id
            }
        }



        results.put("words",techniqueArticleNodes);
        return results;
    }

    @Override
    public Map<String, Object> hotWordsAtlasPaper(Integer topicId, String keyword) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("keyword",keyword);
        Map<String,Object> results = new HashMap<String,Object>();

        List<Map<String,Object>> hotWordNodes = new ArrayList<Map<String,Object>>();//热词节点
        List<Map<String,Object>> paperNodes = new ArrayList<Map<String,Object>>();//论文节点
        List<Map<String,Object>> patentNodes = new ArrayList<Map<String,Object>>();//专利节点
        List<Map<String,Object>> authorNodes = new ArrayList<Map<String,Object>>();//专家节点
        List<Map<String,Object>> organizationNodes = new ArrayList<Map<String,Object>>();//机构节点

//        hotWordNodes = techniqueWordDao.getHotwords(params);//获取领域属于热词的关键词

        List<Map<String,Object>> hotwordPaper = paperDao.getPaperByHotword(params);
        List<Object> paperIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        for (Map<String,Object> paper:hotwordPaper
                ) {
            if(!paperIdParams.contains(paper.get("paperid"))){
                Map<String,Object> papernode = new HashMap<String,Object>();//创建论文节点
                papernode.put("id","paper_"+paper.get("paperid"));
                papernode.put("label",paper.get("title"));
                paperNodes.add(papernode);
                paperIdParams.add(paper.get("paperid"));
            }
//            Map<String,Object> hotwordPaperEdge = new HashMap<String,Object>();//创建热词论文关系
//            hotwordPaperEdge.put("sourceID",paper.get("wordid"));
//            hotwordPaperEdge.put("targetID","paper_"+paper.get("paperid"));
//            hotwordPaperEdges.add(hotwordPaperEdge);
//            computeSize(hotwordSize,paper.get("wordid"));
        }


        results.put("words",paperNodes);
        return results;
    }

    @Override
    public Map<String, Object> hotWordsAtlasPatent(Integer topicId, String keyword) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("keyword",keyword);
        Map<String,Object> results = new HashMap<String,Object>();

        List<Map<String,Object>> hotWordNodes = new ArrayList<Map<String,Object>>();//热词节点
        List<Map<String,Object>> patentNodes = new ArrayList<Map<String,Object>>();//专利节点
        List<Map<String,Object>> authorNodes = new ArrayList<Map<String,Object>>();//专家节点
        List<Map<String,Object>> organizationNodes = new ArrayList<Map<String,Object>>();//机构节点

//        hotWordNodes = techniqueWordDao.getHotwords(params);//获取领域属于热词的关键词


        List<Map<String,Object>> hotwordPatent = patentDao.getPatentByHotword(params);
        List<Object> patentIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        for (Map<String,Object> patent:hotwordPatent
                ) {
            if(!patentIdParams.contains(patent.get("patentid"))){
                Map<String,Object> patendnode = new HashMap<String,Object>();//创建专利节点
                patendnode.put("id","patent_"+patent.get("patentid"));
                patendnode.put("label",patent.get("title"));
                patentNodes.add(patendnode);
                patentIdParams.add(patent.get("patentid"));
            }
//            Map<String,Object> hotwordPatenddge = new HashMap<String,Object>();//创建专利与热词关系
//            hotwordPatenddge.put("sourceID",patent.get("wordid"));
//            hotwordPatenddge.put("targetID","patent_"+patent.get("patentid"));
//            hotwordPatentEdges.add(hotwordPatenddge);
//            computeSize(hotwordSize,patent.get("wordid"));
        }
        results.put("words",patentNodes);
        return results;
    }

    @Override
    public Map<String, Object> hotWordsAtlas(Integer topicId, String keyword) {
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("keyword",keyword);
        Map<String,Object> results = new HashMap<String,Object>();
        List<Map<String,Object>> nodes = new ArrayList<Map<String,Object>>();//节点列表
        List<Map<String,Object>> edges = new ArrayList<Map<String,Object>>();//关系列表

        List<Map<String,Object>> hotWordNodes = new ArrayList<Map<String,Object>>();//热词节点
        List<Map<String,Object>> techniqueArticleNodes = new ArrayList<Map<String,Object>>();//网络新闻动态节点
        List<Map<String,Object>> paperNodes = new ArrayList<Map<String,Object>>();//论文节点
        List<Map<String,Object>> patentNodes = new ArrayList<Map<String,Object>>();//专利节点
        List<Map<String,Object>> authorNodes = new ArrayList<Map<String,Object>>();//专家节点
        List<Map<String,Object>> organizationNodes = new ArrayList<Map<String,Object>>();//机构节点

        List<Map<String,Object>> hotwordArticleEdges = new ArrayList<Map<String,Object>>();//热词与网络新闻动态关系
        List<Map<String,Object>> hotwordPaperEdges = new ArrayList<Map<String,Object>>();//热词与论文节点
        List<Map<String,Object>> hotwordPatentEdges = new ArrayList<Map<String,Object>>();//热词与专利节点
        List<Map<String,Object>> orgTechEdges = new ArrayList<Map<String,Object>>();//机构与网络新闻动态关系
        List<Map<String,Object>> authorTechEdges = new ArrayList<Map<String,Object>>();//专家与网络新闻动态关系
        List<Map<String,Object>> authorPaperEdges = new ArrayList<Map<String,Object>>();//专家与论文关系
        List<Map<String,Object>> authorPatentEdges = new ArrayList<Map<String,Object>>();//专家与专利关系
        List<Map<String,Object>> authorOrgEdges = new ArrayList<Map<String,Object>>();//专家与机构关系

        Map<Object,Integer> hotwordSize = new HashMap<Object,Integer>();
        Map<Object,Integer> authorSize = new HashMap<Object,Integer>();
        Map<Object,Integer> orgSize = new HashMap<Object,Integer>();

        hotWordNodes = techniqueWordDao.getHotwords(params);//获取领域属于热词的关键词
        List<Map<String,Object>> hotwordArticle = techArticleDao.getArticleByHotword(params);
        List<Object> articleIdParams = new ArrayList<Object>();//用于传递参数的网络新闻动态id的集合
        for (Map<String,Object> article:hotwordArticle
             ) {
            if(!articleIdParams.contains(article.get("articleid"))){
                Map<String,Object> techniqueArticle = new HashMap<String,Object>();//创建网络动态节点
                techniqueArticle.put("id","tech_"+article.get("articleid"));
                techniqueArticle.put("label",article.get("title"));
                techniqueArticleNodes.add(techniqueArticle);
                articleIdParams.add(article.get("articleid"));//保存每个网络新闻动态的id
            }
            Map<String,Object> hotwordArticleEdge = new HashMap<String,Object>();//创建热词网络动态关系
            hotwordArticleEdge.put("sourceID",article.get("wordid"));
            hotwordArticleEdge.put("targetID","tech_"+article.get("articleid"));
            hotwordArticleEdges.add(hotwordArticleEdge);
            computeSize(hotwordSize,article.get("wordid"));
        }

        List<Map<String,Object>> hotwordPaper = paperDao.getPaperByHotword(params);
        List<Object> paperIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        for (Map<String,Object> paper:hotwordPaper
                ) {
            if(!paperIdParams.contains(paper.get("paperid"))){
                Map<String,Object> papernode = new HashMap<String,Object>();//创建论文节点
                papernode.put("id","paper_"+paper.get("paperid"));
                papernode.put("label",paper.get("title"));
                paperNodes.add(papernode);
                paperIdParams.add(paper.get("paperid"));
            }
            Map<String,Object> hotwordPaperEdge = new HashMap<String,Object>();//创建热词论文关系
            hotwordPaperEdge.put("sourceID",paper.get("wordid"));
            hotwordPaperEdge.put("targetID","paper_"+paper.get("paperid"));
            hotwordPaperEdges.add(hotwordPaperEdge);
            computeSize(hotwordSize,paper.get("wordid"));
        }

        List<Map<String,Object>> hotwordPatent = patentDao.getPatentByHotword(params);
        List<Object> patentIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        for (Map<String,Object> patent:hotwordPatent
                ) {
            if(!patentIdParams.contains(patent.get("patentid"))){
                Map<String,Object> patendnode = new HashMap<String,Object>();//创建专利节点
                patendnode.put("id","patent_"+patent.get("patentid"));
                patendnode.put("label",patent.get("title"));
                patentNodes.add(patendnode);
                patentIdParams.add(patent.get("patentid"));
            }
            Map<String,Object> hotwordPatenddge = new HashMap<String,Object>();//创建专利与热词关系
            hotwordPatenddge.put("sourceID",patent.get("wordid"));
            hotwordPatenddge.put("targetID","patent_"+patent.get("patentid"));
            hotwordPatentEdges.add(hotwordPatenddge);
            computeSize(hotwordSize,patent.get("wordid"));
        }

        params.put("relArticleList",articleIdParams);
        params.put("relPaperList",paperIdParams);
        params.put("relPatentList",patentIdParams);
        List<Map<String,Object>> relAuthors = authorDao.getAuthorByHotword(params);
        List<Object> tmpAuthorIds = new ArrayList<Object>();//临时存放专家id的list，用于去重
        for (Map<String,Object> relAuthor:relAuthors
             ) {
            Object authorid = relAuthor.get("authorid");
            if(!tmpAuthorIds.contains(authorid)){//判断专家id是否已经出现过
                Map<String,Object> authorNode = new HashMap<String,Object>();//创建专家节点
                authorNode.put("id","author_"+relAuthor.get("authorid"));
                authorNode.put("label",relAuthor.get("name"));
                authorNodes.add(authorNode);
                tmpAuthorIds.add(authorid);//标记该专家已经出现过
            }
            if("0".equals(relAuthor.get("reltype"))){//创建专家与网络动态关系
                Map<String,Object> authorArticleEdge = new HashMap<String,Object>();
                authorArticleEdge.put("sourceID","author_"+relAuthor.get("authorid"));
                authorArticleEdge.put("targetID","tech_"+relAuthor.get("targetID"));
                authorTechEdges.add(authorArticleEdge);
                computeSize(authorSize,"author_"+relAuthor.get("authorid"));
            }
            if("1".equals(relAuthor.get("reltype"))){//创建专家与论文关系
                Map<String,Object> authorPaperEdge = new HashMap<String,Object>();
                authorPaperEdge.put("sourceID","author_"+relAuthor.get("authorid"));
                authorPaperEdge.put("targetID","paper_"+relAuthor.get("targetID"));
                authorPaperEdges.add(authorPaperEdge);
                computeSize(authorSize,"author_"+relAuthor.get("authorid"));
            }
            if("2".equals(relAuthor.get("reltype"))) {//创建专家与专利关系{
                Map<String, Object> authorPatentEdge = new HashMap<String, Object>();
                authorPatentEdge.put("sourceID","author_"+relAuthor.get("authorid"));
                authorPatentEdge.put("targetID","patent_"+relAuthor.get("targetID"));
                authorPatentEdges.add(authorPatentEdge);
                computeSize(authorSize,"author_"+relAuthor.get("authorid"));
            }
        }

        List<Map<String,Object>> relOrgs = organizationDao.getOrgByArticle(params);
        List<Object> tmpOrgIds = new ArrayList<Object>();//临时存放机构id的list，用于去重
        for (Map<String,Object> relorg:relOrgs
             ) {
            Object orgid = relorg.get("orgid");
            if(!tmpOrgIds.contains(orgid)){
                Map<String,Object> orgNode = new HashMap<String,Object>();//创建机构节点
                orgNode.put("id","org_"+relorg.get("orgid"));
                orgNode.put("label",relorg.get("name"));
                organizationNodes.add(orgNode);
                tmpOrgIds.add(orgid);//标记该机构已经出现过
            }
            Map<String,Object> orgArticleEdge = new HashMap<String,Object>();
            orgArticleEdge.put("sourceID","org_"+relorg.get("orgid"));
            orgArticleEdge.put("targetID","tech_"+relorg.get("targetID"));
            orgTechEdges.add(orgArticleEdge);
            computeSize(orgSize,"org_"+relorg.get("orgid"));
        }

        params.put("tmpAuthorIds",tmpAuthorIds);
        params.put("tmpOrgIds",tmpOrgIds);
        List<Map<String,Object>> relAuthorOrgs = organizationDao.getAuthorOrgRelations(params);//创建专家和机构之间的关系
        for (Map<String,Object> relAuthorOrg:relAuthorOrgs
             ) {
            Map<String,Object> authorOrgEdge = new HashMap<String,Object>();
            authorOrgEdge.put("sourceID","author_"+relAuthorOrg.get("sourceID"));
            authorOrgEdge.put("targetID","org_"+relAuthorOrg.get("targetID"));
            authorOrgEdges.add(authorOrgEdge);
            computeSize(orgSize,"org_"+relAuthorOrg.get("targetID"));
        }

        for (Map<String,Object> hotword:hotWordNodes
             ) {//给热词节点的size属性赋值
            Integer size = hotwordSize.get(hotword.get("id"));
            hotword.put("size",size==null?0:size);
        }
        for (Map<String,Object> authorNode:authorNodes
                ) {//给热词节点的size属性赋值
            Integer size = authorSize.get(authorNode.get("id"));
            authorNode.put("size",size==null?0:size);
        }
        for (Map<String,Object> orgnode:organizationNodes
                ) {//给热词节点的size属性赋值
            Integer size = orgSize.get(orgnode.get("id"));
            orgnode.put("size",size==null?0:size);
        }

        //将所有节点增加到nodes集合中
        nodes.addAll(hotWordNodes);
        nodes.addAll(authorNodes);
        nodes.addAll(organizationNodes);
        nodes.addAll(techniqueArticleNodes);
        nodes.addAll(paperNodes);
        nodes.addAll(patentNodes);
        //将所有关系增加到edges集合中
        edges.addAll(hotwordArticleEdges);
        edges.addAll(hotwordPaperEdges);
        edges.addAll(hotwordPatentEdges);
        edges.addAll(orgTechEdges);
        edges.addAll(authorTechEdges);
        edges.addAll(authorPaperEdges);
        edges.addAll(authorPatentEdges);
        edges.addAll(authorOrgEdges);
        //将关系和节点列表添加到结果集中
        results.put("nodes",nodes);
        results.put("edges",edges);
        return results;
    }

    private void computeSize(Map<Object,Integer> nodeSize,Object nodeId){
        Integer size = nodeSize.get(nodeId);
        nodeSize.put(nodeId,size==null?1:++size);
    }

    @Override
    public Map<String, Object> hotWordDevelopmentTrend(Integer topicId,Integer topnumber, String[] words,Date startDate, Date endDate,String category) {
        Map<String,Object> params = new HashMap<String,Object>();
        Map<String,Object> results = new HashMap<String,Object>();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy");
        List<Map<String,Object>> totaldata = new ArrayList<Map<String,Object>>();
        List<Object> years = new ArrayList<Object>();
        Map<String,Object> hotwordNum = new HashMap<String,Object>();//hotwordNum存放结构:key是每个关键词，value是一个长度years一样的数组。
        params.put("topicId",topicId);
        params.put("startDate",startDate);
        params.put("endDate",endDate);
        params.put("topnumber",topnumber==null?5:topnumber);
        params.put("category",category);

        totaldata = techArticleDao.StatisticsNumByHotwordAndYear(params);
        for (Map<String,Object> data:totaldata//获取年份列表
                ) {
            Object year = data.get("publishyear")==null?Long.parseLong(sf.format(startDate)):data.get("publishyear");
            if(!years.contains(year)){
                years.add(year);
            }
        }
        for (Map<String,Object> data:totaldata
                ) {
            String hotword = (String)data.get("keyword");
            Object year = data.get("publishyear")==null?Long.parseLong(sf.format(startDate)):data.get("publishyear");
            if(hotwordNum.get(hotword)==null){
                int[] yearnum = new int[years.size()];//数组的长度与年度list长度一样，数组的值与年度一一对应，数组默认值是0
                yearnum[years.indexOf(year)] = data.get("sumnum")==null?0:((BigDecimal) data.get("sumnum")).intValue();//将统计数字放到对应的年份中去
                hotwordNum.put(hotword,yearnum);
            }else{
                int[] yearnum = (int[])hotwordNum.get(hotword);
                yearnum[years.indexOf(year)] = data.get("sumnum")==null?0:((BigDecimal) data.get("sumnum")).intValue();//将统计数字放到对应的年份中去
            }
        }
        //results.put("articleNum",techArticleDao.StatisticsNumByHotwordAndYear(params));
        //results.put("paperNum",paperDao.StatisticsNumByHotwordAndYear(params));
        //results.put("patentNum",patentDao.StatisticsNumByHotwordAndYear(params));
        results.put("years",years);
        results.put("hotwordNums",hotwordNum);
        return results;
    }
    @Override
    public Map<String, Object> hotWordDevelopmentTrend(Integer topicId,Integer topnumber, String[] words,Date startDate, Date endDate) {
        Map<String,Object> params = new HashMap<String,Object>();
        Map<String,Object> results = new HashMap<String,Object>();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy");
        List<Map<String,Object>> totaldata = new ArrayList<Map<String,Object>>();
        List<Object> years = new ArrayList<Object>();
        Map<String,Object> hotwordNum = new HashMap<String,Object>();//hotwordNum存放结构:key是每个关键词，value是一个长度years一样的数组。
        params.put("topicId",topicId);
        params.put("startDate",startDate);
        params.put("endDate",endDate);
        params.put("topnumber",topnumber==null?5:topnumber);
        totaldata = techArticleDao.StatisticsNumByHotwordAndYear(params);
        for (Map<String,Object> data:totaldata//获取年份列表
             ) {
            Object year = data.get("publishyear")==null?Long.parseLong(sf.format(startDate)):data.get("publishyear");
            if(!years.contains(year)){
                years.add(year);
            }
        }
        for (Map<String,Object> data:totaldata
                ) {
            String hotword = (String)data.get("keyword");
            Object year = data.get("publishyear")==null?Long.parseLong(sf.format(startDate)):data.get("publishyear");
            if(hotwordNum.get(hotword)==null){
                int[] yearnum = new int[years.size()];//数组的长度与年度list长度一样，数组的值与年度一一对应，数组默认值是0
                yearnum[years.indexOf(year)] = data.get("sumnum")==null?0:((BigDecimal) data.get("sumnum")).intValue();//将统计数字放到对应的年份中去
                hotwordNum.put(hotword,yearnum);
            }else{
                int[] yearnum = (int[])hotwordNum.get(hotword);
                yearnum[years.indexOf(year)] = data.get("sumnum")==null?0:((BigDecimal) data.get("sumnum")).intValue();//将统计数字放到对应的年份中去
            }
        }
        //results.put("articleNum",techArticleDao.StatisticsNumByHotwordAndYear(params));
        //results.put("paperNum",paperDao.StatisticsNumByHotwordAndYear(params));
        //results.put("patentNum",patentDao.StatisticsNumByHotwordAndYear(params));
        results.put("years",years);
        results.put("hotwordNums",hotwordNum);
        return results;
    }

    @Override
    public Map<String, Object> coWordAnalysis(Integer topicId) {
        return coWordAnalysis(topicId,null);
    }

    @Override
    public Map<String, Object> coWordAnalysis(Integer topicId,String category) {
        Map<String,Object> results = new HashMap<String,Object>();
        List<Map<String,Object>> nodes = new ArrayList<Map<String,Object>>();
        List<Map<String,Object>> edges = new ArrayList<Map<String,Object>>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("category",category);
        List<Map<String,Object>> hotwordRelations = techniqueWordDao.getHotwordsByRelation(params);
        List<Object> tmpHotwordIds = new ArrayList<Object>();//临时存放热词id的list，用于去重
        Map<String,Object> articleIncludeWords = new HashMap<String,Object>();//用于记录每个动态包含的关键词
        Map<String,Integer> relIndex = new HashMap<String,Integer>();//用于记录每个关系在Edges中的下标
        for (Map<String,Object> wordRelation:hotwordRelations
             ) {
            Object wordid = wordRelation.get("wordid");
            Object articleid = wordRelation.get("articleid");
            if(!tmpHotwordIds.contains(wordid)){
                Map<String,Object> wordNode = new HashMap<String,Object>();//创建机构节点
                wordNode.put("id",wordRelation.get("wordid"));
                wordNode.put("label",wordRelation.get("keyword"));
                wordNode.put("weight",1);
                nodes.add(wordNode);
                tmpHotwordIds.add(wordid);//标记该热词已经出现过
            }else{//更新热词权重
                Map<String,Object> wordNode = nodes.get(tmpHotwordIds.indexOf(wordid));
                Integer weight = ((Integer)wordNode.get("weight"))+1;
                wordNode.put("weight",weight);
            }
            List<Object> articleWords = (List<Object>)articleIncludeWords.get(articleid.toString());
            if (articleWords==null){//如果该动态中没有关键词则增加该条记录的热词
                articleWords = new ArrayList<Object>();
                articleWords.add(wordid);
                articleIncludeWords.put(articleid.toString(),articleWords);
            }else{//如果该动态中存在关键词，则根据该条记录的关键词创建关系节点
                for (Object articleWord:articleWords
                     ) {
                    if(wordid.equals(articleWord))//如果关键词一样则跳过
                        continue;
                    Map<String,Object> wordRelEdge = new HashMap<String,Object>();
                    String indexKey = wordid+"REL"+articleWord;//自定义的键，用于存放每个关系在edges中的下标
                    if(relIndex.get(indexKey)==null){//如果不存关系则创建关系
                        wordRelEdge.put("sourceID",wordid);
                        wordRelEdge.put("targetID",articleWord);
                        wordRelEdge.put("size",1);
                        relIndex.put(indexKey,edges.size());//存入该关系的下标
                        edges.add(wordRelEdge);
                    }else{//如果处在关系则更新关系的size
                        wordRelEdge = edges.get(relIndex.get(indexKey));
                        Integer size = (Integer) wordRelEdge.get("size");
                        size+=1;
                        wordRelEdge.put("size",size);//size加1，代表两个热词共同出现的次数加1
                    }
                }
                articleWords.add(wordid);
            }
        }
        results.put("nodes",nodes);
        results.put("edges",edges);
        return results;
    }
    /**
     * 热词详情
     * @param wordId 某个领域的一个或者多个主题关键词
     * @param  topicId 技术领域id
     * @return
     */
    public Map<String,Object>  hotWordDetail(Integer topicId,Integer wordId){
        Map<String,Object> results = new HashMap<String,Object>();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("wordId",wordId);

        List<Object> articleIdParams = new ArrayList<Object>();//用于传递参数的网络新闻动态id的集合
        List<Object> paperIdParams = new ArrayList<Object>();//用于传递参数的论文id的集合
        List<Object> patentIdParams = new ArrayList<Object>();//用于传递参数的专利id的集合
        List<Object> orgIdParams = new ArrayList<Object>();//用于传递参数的机构id的集合
        List<Object> authorIdParams = new ArrayList<Object>();//用于传递参数的专家id的集合

        List<Map<String,Object>> relatedWords = techniqueWordDao.getHotwords(params);

        List<Map<String,Object>> relations = techniqueWordDao.getHotwordRelations(params);
        for (Map<String,Object> relation:relations
             ) {
            if("0".equals(relation.get("type").toString())) {//创建专家与专利关系{
                articleIdParams.add(relation.get("articleid"));
            }
            if("1".equals(relation.get("type").toString())) {//创建专家与专利关系{
                paperIdParams.add(relation.get("articleid").toString());
            }
            if("2".equals(relation.get("type"))) {//创建专家与专利关系{
                patentIdParams.add(relation.get("articleid"));
            }
        }
        params.put("relArticleList",articleIdParams);
        params.put("relPaperList",paperIdParams);
        params.put("relPatentList",patentIdParams);
        System.out.println(articleIdParams.size()+"----"+paperIdParams.size()+"----"+patentIdParams.size());
        List<Map<String,Object>> hotwordAuthors = authorDao.getAuthorByHotword(params);
        List<String> relatedAuthors = new ArrayList<String>();
        for (Map<String,Object> hotwordAuthor:hotwordAuthors
                ) {
            if(!authorIdParams.contains(hotwordAuthor.get("authorid"))){
                authorIdParams.add(hotwordAuthor.get("authorid"));
                relatedAuthors.add((String)hotwordAuthor.get("name"));
            }
        }

        List<String> relatedOrgs = new ArrayList<String>();
        List<Map<String,Object>> articleOrgs = organizationDao.getOrgByArticle(params);
        for (Map<String,Object> articleOrg:articleOrgs
             ) {
            if(!orgIdParams.contains(articleOrg.get("orgid"))){
                orgIdParams.add(articleOrg.get("orgid"));
                relatedOrgs.add((String)articleOrg.get("name"));
            }
        }
        List<Map<String,Object>> paperAndPatentOrgs = organizationDao.getOrgRelPaperAndPatent(params);
        for (Map<String,Object> paperAndPatentOrg:paperAndPatentOrgs
                ) {
            if(!orgIdParams.contains(paperAndPatentOrg.get("orgid"))){
                orgIdParams.add(paperAndPatentOrg.get("orgid"));
                relatedOrgs.add((String)paperAndPatentOrg.get("orgname"));
            }
        }

        results.put("relatedWords",relatedWords);//相关热词
        results.put("relatedAuthors",relatedAuthors);//相关专家
        results.put("relatedOrgs",relatedOrgs);//相关机构
        return results;
    }

    /**
     * 论文详情
     * @param paperId 某个领域的一个或者多个主题关键词
     * @return
     */
    public Map<String,Object>  paperDetail(Integer paperId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("id",paperId);
        Map<String,Object> paper = new HashMap<String,Object>();
        List<Map<String,Object>> papers = paperDao.getPaperById(params);
        if(papers!=null&&papers.size()>0)
            paper = papers.get(0);
        return paper;
    }
    /**
     * 专利详情
     * @param patentId 某个领域的一个或者多个主题关键词
     * @return
     */
    public Map<String,Object>  patentDetail(Integer patentId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("id",patentId);
        Map<String,Object> patent = new HashMap<String,Object>();
        List<Map<String,Object>> patents = patentDao.getPatentById(params);
        if(patents!=null&&patents.size()>0)
            patent = patents.get(0);
        return patent;
    }
    /**
     * 专家详情
     * @param authorId 某个领域的一个或者多个主题关键词
     * @return
     */
    public Map<String,Object>  authorDetail(Integer authorId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("authorId",authorId);
        Map<String,Object> paper = new HashMap<String,Object>();
        List<Map<String,Object>> papers = authorDao.getAuthorByID(params);
        if(papers!=null&&papers.size()>0)
            paper = papers.get(0);
        return paper;
    }
    /**
     * 机构详情
     * @param orgId 某个领域的一个或者多个主题关键词
     * @return
     */
    public Map<String,Object>  orgDetail(Integer orgId){
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("orgId",orgId);
        Map<String,Object> patent = new HashMap<String,Object>();
        List<Map<String,Object>> patents = organizationDao.getOrgByID(params);
        if(patents!=null&&patents.size()>0)
            patent = patents.get(0);
        return patent;
    }
    /**
     * 获得某领域相关热词
     * @param topicId 某个领域id
     * @param type 新闻动态 0、论文 1、专利 2 综合 all
     */
    public List<Map<String,Object>> getHotwordByType(Integer topicId,String type){
        List<Map<String,Object>> hotWordNodes = new ArrayList<Map<String,Object>>();//热词节点
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("topicId",topicId);
        params.put("type",type);
        hotWordNodes = techniqueWordDao.getHotwordByType(params);//获取领域属于热词的关键词
        return hotWordNodes;
    }
}
